package top.stacktrace.account.service;

import cn.hutool.crypto.digest.DigestAlgorithm;
import cn.hutool.crypto.digest.Digester;
import io.seata.core.context.RootContext;
import io.seata.rm.tcc.api.BusinessActionContext;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CachePut;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import top.stacktrace.account.dao.AccountDao;
import top.stacktrace.account.domain.LoginVo;
import top.stacktrace.account.domain.User;

import java.nio.charset.StandardCharsets;
import java.util.Objects;

@Service
public class AccountService implements TccService {
    @Autowired
    private AccountDao orderDao;

    private static Digester ds = new Digester(DigestAlgorithm.SHA256);
    static{
        ds.setSalt("DKLKJLEIFOJIEWLSJLFOIEWF".getBytes(StandardCharsets.UTF_8));
    }

    public static void main(String[] args){
        System.out.println(ds.digestHex("123456"));
    }

    @Cacheable(value = "user",key = "#name")
    public User getByName(String name){
        return orderDao.getUserByName(name);
    }

    @CachePut(value="user",key="#user.id")
    public User saveUserCache(User user){
        return user;
    }

    public User login(LoginVo v){
        User u = getByName(v.getName());
        if(Objects.nonNull(u) && ds.digestHex(v.getPass()).equals(u.getPass())){
            u = this.saveUserCache(u);
            return u;
        }
        return new User();
    }

    @Override
    @Transactional
    public boolean pay(long userid,int n){
        int ret = orderDao.deCreaseReserve(userid,n);
        if(ret > 0){
            orderDao.saveXA(RootContext.getXID());
        }
        return ret > 0;
    }

    @Override
    public void commitTcc(BusinessActionContext context) {
        orderDao.delXA(context.getXid());
    }

    @Override
    @Transactional
    public void cancel(BusinessActionContext context) {
        if(orderDao.countXA(context.getXid()) > 0){
            orderDao.inCreaseBalance((int)context.getActionContext("userid"),(int)context.getActionContext("n"));
            orderDao.delXA(context.getXid());
        }
    }
}
